import 'dotenv/config';
import './utils/logger.js';

import { checkFileExists, readFile } from './utils/index.js';
import { initData, store } from './store.js';
import { initWs, onMessage, sendMessage } from './utils/websocket.js';

import WK from './workerManager/index.js';
import { config } from 'dotenv';
import fs from 'node:fs';
import path from 'path';
import { taskMap } from './taskMap.js';

// 根据 NODE_ENV 变量加载对应的环境文件

const env = process.env.NODE_ENV || 'development';
const envPath = path.resolve(process.cwd(), `.env.${env}`);

config({ path: envPath });

console.log('NODE_ENV>', process.env.NODE_ENV);

console.log('WSS>', process.env.WSS);
/**
 * Constants
 */

/**
 * Events
 */
/**
 * 初始化 WebSocket
 */
initWs();

/**
 * 收到消息
 */
onMessage(async (data) => {
    console.log('onMessage >>', data);
    // try {
    const payload = JSON.parse(data);

    // 挂载 initData
    if (payload.appInfo) {
        const appInfo = payload.appInfo;
        const appName = appInfo.appId + '_' + appInfo.appReleaseType;
        if (payload.initData) {
            if (initData[appName] && initData[appName][appInfo.userId]) delete initData[appName][appInfo.userId];
        } else {
            // console.log('initData', JSON.stringify(initData), initData[appName] && initData[appName][appInfo.userId])
            if (initData[appName] && initData[appName][appInfo.userId]) {
                initData[appName][appInfo.userId].timeStamp = Date.now();
                payload.initData = initData[appName][appInfo.userId].data;
            }
        }
    }

    // 服务端启动应用
    if (payload.type === 'start') {
        const path = await handleBackgroundFile(payload.appInfo);
        let wk = WK.createWorker(payload, path);
        // 由于create的时候count从1开始，这里不单独使用woker的话需要-1
        wk.count--;
    }
    // 关闭小应用
    if (payload.type === 'stop') {
        WK.stopWorker(payload.appInfo);
        console.log('回复后端stop');
        sendMessage(
            JSON.stringify({
                ...payload,
                type: 'response',
                result: {
                    code: 200,
                    type: 'stop',
                },
            }),
        );
    }

    // 上报
    if (payload.type === 'subscribe') {
        console.log('上subscribe---payload', payload);
        let wk = WK.getWorker(payload);
        wk?.worker.postMessage({
            ...payload,
            cmd: {
                fn: 'subscribe',
            },
        });
    }

    // 所有任务
    if (taskMap.includes(payload.type)) {
        let wk = WK.getWorker(payload);
        if (payload.type == 'subscribe') {
            return false;
        }
        wk?.worker?.postMessage({
            ...payload,
            cmd: {
                fn: payload.type,
            },
        });
    }

    // 消息回执
    if (payload.type === 'response') {
        const msg = store[payload.id];
        //
        if (msg !== undefined) {
            if (msg?.wk) {
                msg.wk.count++;
                msg.wk.createTime = Date.now();
                msg.wk.worker?.postMessage(payload);
            }

            delete store[payload.id];
        }
    }

    // 服务器给节点：调用命令 需要调用bgjs返回结果给后端
    if (payload.type === 'cmd') {
        let wk = WK.getWorker(payload);
        wk?.worker?.postMessage(payload);
    }
    // } catch (error) {
    //     console.error('onMessage error:>>>', JSON.stringify(error))
    // }
});

/**
 * 处理后台文件
 */
async function handleBackgroundFile(appInfo) {
    // 判断目录下是否有这个应用 appid + version + appReleaseType
    const fileName = `${appInfo.appId + '-' + appInfo.appReleaseType}`;
    const folderPath = path.join(path.resolve(), './tmp');

    // 生成路径
    const tmpPath = path.join(path.resolve(), `./tmp/${fileName}.js`);

    // 是否下载过应用
    // if (checkFileExists(folderPath, fileName + '.js')) {
    //     return tmpPath
    // }

    // 远程用户的代码：001
    const appletJS = await readFile(appInfo.jsUrl);
    // 用户写的小应用的后台运行的js代码写作内容:文件 jeejio-background.js
    // 文件内容方式：https://ox8zrpl57d.feishu.cn/wiki/BgDhwTXrfiX3a8kNi7rcmmB7nif
    // 给用户的代码增加：header和footer内容：具体例子如下查看：
    // 远程用户的代码：案例：读取 service worker
    // const appletJS = fs.readFileSync('./applet/background.js', 'utf-8');

    // 读取 inject
    const injectHeader = fs.readFileSync('./src/inject/header.js', 'utf-8');
    // TODO:sdk没有版本概念 暂时不下载最新的 在header中写死了
    // const sdk = await readFile('http://developer.devjeejio.com/sdk.dev.js')

    const injectFooter = fs.readFileSync('./src/inject/footer.js', 'utf-8');

    // 写入内容
    fs.writeFileSync(tmpPath, `${injectHeader}\n${appletJS}\n${injectFooter}`, 'utf-8');

    return tmpPath;
}
